const webpack = require('webpack'),
    WebpackDevServer = require("webpack-dev-server"),
    webpackConfig = require("./webpack.config.js"),
    path = require('path'),
    fs = require('fs'),
    opn = require('opn'),
    gulp = require('gulp'),
    clean = require('gulp-clean'),
    gutil = require('gulp-util'),
    less = require('gulp-less'),
    notify = require('gulp-notify'),
    plumber = require('gulp-plumber'),
    gulpif = require('gulp-if'),
    sprity = require('sprity'),
    imagemin = require('gulp-imagemin'),
    sourcemaps = require('gulp-sourcemaps'),
    eslint = require('gulp-eslint'),
    config = require('./config.js');


gulp.task('default', ['webpack-dev-server']);

gulp.task("clean", function () {
    return gulp.src('dist/*')
        .pipe(clean());
});

gulp.task("build-dev", ["webpack:build-dev"], function () {
    gulp.watch(["js/**/*"], ["webpack:build-dev"]);
});

// Production build
gulp.task("build", ['clean', 'sprites', "webpack:build"]);

gulp.task("webpack:build", function (callback) {
    // modify some webpack config options
    var myConfig = Object.create(webpackConfig);
    myConfig.plugins = myConfig.plugins.concat(
        new webpack.DefinePlugin({
            "process.env": {
                // This has effect on the react lib size
                "NODE_ENV": JSON.stringify("production")
            }
        }),
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.UglifyJsPlugin()
    );

    // run webpack
    webpack(myConfig, function (err, stats) {
        if (err) throw new gutil.PluginError("webpack:build", err);
        gutil.log("[webpack:build]", stats.toString({
            colors: true
        }));
        callback();
    });
});

// modify some webpack config options
var myDevConfig = Object.create(webpackConfig);
myDevConfig.devtool = "sourcemap";
myDevConfig.debug = true;

// create a single instance of the compiler to allow caching
var devCompiler = webpack(myDevConfig);

gulp.task("webpack:build-dev", function (callback) {
    // run webpack
    devCompiler.run(function (err, stats) {
        if (err) throw new gutil.PluginError("webpack:build-dev", err);
        gutil.log("[webpack:build-dev]", stats.toString({
            colors: true
        }));
        callback();
    });
});

gulp.task("webpack-dev-server", function (callback) {
    // modify some webpack config options
    var myConfig = Object.create(webpackConfig);
    myConfig.devtool = "eval";
    myConfig.debug = true;

    // Start a webpack-dev-server
    new WebpackDevServer(webpack(myConfig), {
        publicPath: "/" + myConfig.output.publicPath,
        stats: {
            colors: true
        }
    }).listen(8080, "localhost", function (err) {
        if (err) throw new gutil.PluginError("webpack-dev-server", err);
        gutil.log("[webpack-dev-server]", "http://localhost:8080/webpack-dev-server/index.html");
        opn('http://localhost:8080/webpack-dev-server/index.html');
    });
});

gulp.task('sprites', function () {
    return sprity.src({
        src: config.sprite.src,
        style: './sprite.css',
        prefix: 'sprite',
        // ... other optional options
        // for example if you want to generate less instead of css
        //processor: 'less', // make sure you have installed sprity-less
    })
        .pipe(gulpif('*.png', gulp.dest(config.image.dist), gulp.dest(config.css.dist)))
});

gulp.task('imagemin', function () {

    return gulp.src(config.image.src)
        .pipe(imagemin())
        .pipe(gulp.dest(config.image.dist));
});

gulp.task('less:build-dev', function () {
    gulp.src(config.less.src)
        .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
        .pipe(sourcemaps.init())
        .pipe(less())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(config.less.dist));
});

gulp.task('less:watch', function () {
    gulp.watch('src/less/**/*.less', ['build-dev']);
});

gulp.task('lint', function () {
    // ESLint ignores files with "node_modules" paths.
    // So, it's best to have gulp ignore the directory as well.
    // Also, Be sure to return the stream from the task;
    // Otherwise, the task may end before the stream has finished.
    return gulp.src([config.js.src, '!node_modules/**'])
        .pipe(eslint({
            extends: 'eslint:recommended',
            ecmaFeatures: {
                'modules': true
            },
            rules: {
                'my-custom-rule': 1,
                'strict': 2
            },
            globals: {
                'jQuery': false,
                '$': true
            },
            envs: [
                'browser'
            ]
        }))
        .pipe(eslint.formatEach('compact', process.stderr));
});